package websocketgulu.demo.pojo;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import websocketgulu.demo.pojo.WaveConstants;

public class WaveFileReader {
    private String filename = null;

    private int[][] data = (int[][])null;

    private int len = 0;

    private String chunkdescriptor = null;

    private long chunksize = 0L;

    private String waveflag = null;

    private String fmtsubchunk = null;

    private long subchunk1size = 0L;

    private int audioformat = 0;

    private int numchannels = 0;

    private long samplerate = 0L;

    private long byterate = 0L;

    private int blockalign = 0;

    private int bitspersample = 0;

    private String datasubchunk = null;

    private long subchunk2size = 0L;

    private FileInputStream fis = null;

    private BufferedInputStream bis = null;

    private boolean issuccess = false;

    public WaveFileReader(String filename) {
        initReader(filename);
    }

    public boolean isSuccess() {
        return this.issuccess;
    }

    public int getBitPerSample() {
        return this.bitspersample;
    }

    public long getSampleRate() {
        return this.samplerate;
    }

    public int getNumChannels() {
        return this.numchannels;
    }

    public int getDataLen() {
        return this.len;
    }

    public int[][] getData() {
        return this.data;
    }

    private void initReader(String filename) {
        this.filename = filename;
        try {
            this.fis = new FileInputStream(this.filename);
            this.bis = new BufferedInputStream(this.fis);
            this.chunkdescriptor = readString(WaveConstants.LENCHUNKDESCRIPTOR);
            if (!this.chunkdescriptor.endsWith("RIFF"))
                throw new IllegalArgumentException("RIFF miss, " + filename + " is not a wave file.");
            this.chunksize = readLong();
            this.waveflag = readString(WaveConstants.LENWAVEFLAG);
            if (!this.waveflag.endsWith("WAVE"))
                throw new IllegalArgumentException("WAVE miss, " + filename + " is not a wave file.");
            this.fmtsubchunk = readString(WaveConstants.LENFMTSUBCHUNK);
            if (!this.fmtsubchunk.endsWith("fmt "))
                throw new IllegalArgumentException("fmt miss, " + filename + " is not a wave file.");
            this.subchunk1size = readLong();
            this.audioformat = readInt();
            this.numchannels = readInt();
            this.samplerate = readLong();
            this.byterate = readLong();
            this.blockalign = readInt();
            this.bitspersample = readInt();
            this.datasubchunk = readString(WaveConstants.LENDATASUBCHUNK);
            if (!this.datasubchunk.endsWith("data"))
                throw new IllegalArgumentException("data miss, " + filename + " is not a wave file.");
            this.subchunk2size = readLong();
            this.len = (int)(this.subchunk2size / (this.bitspersample / 8) / this.numchannels);
            this.data = new int[this.numchannels][this.len];
            for (int i = 0; i < this.len; i++) {
                for (int n = 0; n < this.numchannels; n++) {
                    if (this.bitspersample == 8) {
                        this.data[n][i] = this.bis.read();
                    } else if (this.bitspersample == 16) {
                        this.data[n][i] = readInt();
                    }
                }
            }
            this.issuccess = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (this.bis != null)
                    this.bis.close();
                if (this.fis != null)
                    this.fis.close();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    private String readString(int len) {
        byte[] buf = new byte[len];
        try {
            if (this.bis.read(buf) != len)
                throw new IOException("no more data!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(buf);
    }

    private int readInt() {
        byte[] buf = new byte[2];
        int res = 0;
        try {
            if (this.bis.read(buf) != 2)
                throw new IOException("no more data!!!");
            res = buf[0] & 0xFF | buf[1] << 8;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return res;
    }

    private long readLong() {
        long res = 0L;
        try {
            long[] l = new long[4];
            for (int i = 0; i < 4; i++) {
                l[i] = this.bis.read();
                if (l[i] == -1L)
                    throw new IOException("no more data!!!");
            }
            res = l[0] | l[1] << 8L | l[2] << 16L | l[3] << 24L;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return res;
    }

    private byte[] readBytes(int len) {
        byte[] buf = new byte[len];
        try {
            if (this.bis.read(buf) != len)
                throw new IOException("no more data!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buf;
    }

    public static int[] readSingleChannel(String filename) {
        if (filename == null || filename.length() == 0)
            return null;
        try {
            websocketgulu.demo.pojo.WaveFileReader reader = new websocketgulu.demo.pojo.WaveFileReader(filename);
            int[] res = reader.getData()[0];
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
